package com.tticar.invmanager.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.tticar.invmanager.common.Enum.Status;
import com.tticar.invmanager.common.exception.MyServiceException;
import com.tticar.invmanager.common.shiro.MySecurityUtils;
import com.tticar.invmanager.common.utils.BarcodeUtil;
import com.tticar.invmanager.common.utils.ExcelUtils;
import com.tticar.invmanager.common.utils.MyResponseBody;
import com.tticar.invmanager.entity.*;
import com.tticar.invmanager.entity.vo.*;
import com.tticar.invmanager.mapper.MMaterielMapper;
import com.tticar.invmanager.mapper.MMaterielSkuMapper;
import com.tticar.invmanager.service.IMCateogryService;
import com.tticar.invmanager.service.IMMaterielService;
import com.tticar.invmanager.service.IMMaterielSkuService;
import com.tticar.invmanager.service.ISysTenantService;
import com.tticar.invmanager.tticar.mapper.GoodsMapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 存货表 前端控制器
 * </p>
 *
 * @author joeyYan
 * @since 2018-07-09
 */
@Controller
@RequestMapping("/mMateriel")
public class MMaterielController extends BaseController {

    private final  String[] titles = {"存货名称（必填）", "分类（必填）" , "品牌（必填）" , "供应商（必填）" , "仓库（必填）" , "库位（必填）" ,
            "最低库存（数字）" , "最高库存（数字）" , "计量单位" , "规格/尺寸（必填）" ,"配件编码", "参考进价（数字）", "参考零售价（数字）", "批发价（数字）", "一级会员价（数字）", "二级会员价（数字）", "三级会员价（数字）" };

    @Autowired
    private IMMaterielService mMaterielService;

    @Autowired
    private IMMaterielSkuService mMaterielSkuService;

    @Autowired
    private IMCateogryService mCateogryService;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private MMaterielSkuMapper mskuMapper;
    @Autowired
    private MMaterielMapper mMaterielMapper;
    @Autowired
    private ISysTenantService sysTenantService;

    /**
     * 更新sku.
     *
     * @param mMaterielSku
     * @return
     */
    @PostMapping("sku")
    @ResponseBody
    public MyResponseBody postSku(MMaterielSku mMaterielSku) {
        mMaterielService.edit(mMaterielSku);
        return MyResponseBody.success();
    }

    @PostMapping
    @ResponseBody
    public MyResponseBody post(MMateriel mMateriel, String mMaterielSkuStr, String house, String carBrand) {
        Wrapper wrapper = new EntityWrapper<>();
        wrapper.eq(MMateriel.NAME, mMateriel.getName());
        wrapper.ne("status", Status.DELETE.getCode());
        MMateriel materiel = mMaterielService.selectOne(wrapper);
        if (materiel != null && !materiel.getId().equals(mMateriel.getId())) {
            throw new MyServiceException("该存货商品已存在，请勿重复添加");
        }

        if (mMateriel.getDefaultUintId() == null) {
            throw new MyServiceException("基本信息：默认供应商栏不能为空");
        }
        if (StringUtils.isBlank(house)) {
            throw new MyServiceException("基本信息：仓库库位栏不能为空");
        }

        List<MMaterielSku> mMaterielSkus = JSONArray.parseArray(mMaterielSkuStr, MMaterielSku.class);
        if (CollectionUtils.isEmpty(mMaterielSkus)) {
            throw new MyServiceException("库存价格不能为空");
        }

        // 校验：批发价>一级会员价>二级会员价>三级会员价
        for (MMaterielSku materielSku : mMaterielSkus) {
            if (StringUtils.isBlank(materielSku.getSkus())) {
                throw new MyServiceException("规格型号不能为空");
            }
            Map map = JSON.parseObject(materielSku.getPrices(), Map.class);
            List<BigDecimal> priceList = new ArrayList<>();
            String price0 = (String) map.get("0");
            String price1 = (String) map.get("1");
            String price2 = (String) map.get("2");
            String price3 = (String) map.get("3");
            if (price0 != null && !price0.equals("")) priceList.add(new BigDecimal(price0));
            if (price1 != null && !price1.equals("")) priceList.add(new BigDecimal(price1));
            if (price2 != null && !price2.equals("")) priceList.add(new BigDecimal(price2));
            if (price3 != null && !price3.equals("")) priceList.add(new BigDecimal(price3));

            if (priceList.size() > 1) {
                for (int i = 0; i < priceList.size()-1; i++) {
                    if (priceList.get(i).compareTo(priceList.get(i+1)) <0) {
                        throw new MyServiceException("要求：批发价>=一级会员价>=二级会员价>=三级会员价");
                    }
                }
            }
        }

        List<CarBrandMateriel> carBrandList = JSONArray.parseArray(carBrand, CarBrandMateriel.class);
        mMaterielService.edit(mMateriel, mMaterielSkus, house, carBrandList);
        return MyResponseBody.success();
    }





    @PostMapping("delete")
    @ResponseBody
    public MyResponseBody delete(@RequestParam("ids[]") List<Long> ids) {
        MyResponseBody responseBody = MyResponseBody.success();
        mMaterielService.delete(ids);
        return responseBody;
    }

    @GetMapping("{id}")
    @ResponseBody
    public MyResponseBody get(@PathVariable("id") Long id) {
        MyResponseBody responseBody = MyResponseBody.success();
        responseBody.setData(mMaterielService.getById(id));
        return responseBody;
    }

    @GetMapping("edit")
    public String edit(MMateriel mMateriel, ModelMap modelMap) {
        if (mMateriel.getId() != null) {
            MMateriel materiel = mMaterielService.selectById(mMateriel.getId());
            modelMap.put("categoryId", materiel != null && materiel.getCategoryId() != null ? materiel.getCategoryId() : 0);
            if (materiel != null) {
                MCateogry cateogry = mCateogryService.selectById(materiel.getCategoryId());
                modelMap.put("cateogryName", cateogry != null ? cateogry.getName() : "");
            }
        }
        modelMap.put("id", mMateriel.getId());
        return "/mMateriel/mMateriel_edit";
    }

    @GetMapping("/m/list")
    @ResponseBody
    public Page mlist(MMateriel mMateriel, MyPage<MMateriel> page) {
        return mMaterielService.list(mMateriel, page);
    }

    @GetMapping("list")
    @ResponseBody
    public Page list(MMateriel mMateriel, MyPage<MMateriel> page) {
        return mMaterielService.selectPage(mMateriel, page);
    }

    @PostMapping("skuList")
    @ResponseBody
    public List skuList(Long id) {
        List<Map> skuList = mMaterielMapper.getSkuList(id);
        if (skuList != null && skuList.size() > 0) {
            for (int i = 0; i < skuList.size(); i++) {
                String prices = skuList.get(i).get("prices").toString();
                Map<String,String> parse = (Map<String,String>)JSON.parse(prices);
                skuList.get(i).put("0", parse.get("0"));
                skuList.get(i).put("1", parse.get("1"));
                skuList.get(i).put("2", parse.get("2"));
                skuList.get(i).put("3", parse.get("3"));

            }
        }
        return skuList;
    }

    @GetMapping
    public String index(String searchText, ModelMap map) {
        map.put("searchText", searchText);
        return "/mMateriel/mMateriel";
    }

    @GetMapping("tree")
    public String tree(String name, Integer type, ModelMap modelMap) {
        modelMap.put("name", name);
        modelMap.put("type", type == null ? 1 : type);
        return "/mMateriel/mMaterielTree";
    }

    @PostMapping("/tree")
    @ResponseBody
    public List<Tree> tree(Long id, String searchText, Integer type) {
        if(StringUtils.isEmpty(searchText)) {
            return mMaterielService.tree(id, type);
        }

        return mMaterielService.tree(searchText, type);
    }

    @PostMapping("/treegrid")
    @ResponseBody
    public List<Tree> treegrid(Long id, String searchText, Integer type) {
        if(StringUtils.isEmpty(searchText)) {
            return mMaterielService.tree(id, type);
        }

        return mMaterielService.tree(searchText, type);
    }


    @PostMapping("/treegridForCheck")
    @ResponseBody
    public List<GoodsTreeGrid> treegridForCheck(GoodsTreeGridSearchDto searchDto) {
        return mMaterielService.treegridForCheck(searchDto);
    }

    /**
     * 生成条码对话框
     * @param mMateriel
     * @param modelMap
     * @return
     */
    @GetMapping("barcode")
    public String barcode(MMateriel mMateriel, ModelMap modelMap) {
        Wrapper wrapper = new EntityWrapper<>();
        wrapper.eq("mid", mMateriel.getId());
        wrapper.ne("status", -1);
        List<MMaterielSku> materielSkuList = mMaterielSkuService.selectList(wrapper);
        String skuIds = "";
        if (CollectionUtils.isNotEmpty(materielSkuList)) {
            for (MMaterielSku materielSku : materielSkuList) {
                skuIds += materielSku.getId() + ",";
            }
        }
        modelMap.put("skuIds", skuIds);
        return "/mMateriel/barcode";
    }

    /**
     * 生成条码
     * @param id 商品规格id
     * @return
     */
    @GetMapping("generateBarcode")
    @ResponseBody
    public MyResponseBody generateBarcode(@RequestParam("id") Long id, HttpServletResponse response) {
        MyResponseBody responseBody = MyResponseBody.success();
        MMaterielSku mMaterielSku = mMaterielSkuService.selectById(id);
        if (mMaterielSku == null || StringUtils.isBlank(mMaterielSku.getCode())) {
            throw MyServiceException.getInstance("商品规格数据异常，无法生成条码");
        }
        byte[] barcode = BarcodeUtil.generateByte(mMaterielSku.getTenantId() + "-" + mMaterielSku.getCode());
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            out.write(barcode);
            out.flush();
        } catch (Exception e){
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseBody;
    }

    /**
     * 导入对话框
     * @param modelMap
     * @return
     */
    @GetMapping("importExcel")
    public String importExcel(ModelMap modelMap) {
        return "/mMateriel/importExcel";
    }

    /**
     * 导入Excel
     * @param excelFile
     * @return
     */
    @PostMapping("saveExcel")
    @ResponseBody
    public MyResponseBody saveExcel(@RequestParam("excelFile") MultipartFile excelFile) throws Exception {
        MyResponseBody myResponseBody = MyResponseBody.success("导入成功");
        List<List<String>> list = ExcelUtils.getExcelSheet(excelFile, titles);
        mMaterielService.importExcel(list);
        return myResponseBody;
    }

    /**
     * 下载Excel模板
     * @return
     */
    @GetMapping("downLoadTemplet")
    @ResponseBody
    public void downLoadTemplet(HttpServletResponse response) {

        HSSFWorkbook wb = null;
        OutputStream output = null;
        try {
            wb = ExcelUtils.createExcel(titles);
            output = response.getOutputStream();
            response.addHeader("Content-Disposition", "inline;filename=" + java.net.URLEncoder.encode("存货商品导入模板.xls", "UTF-8"));
            response.setContentType("application/ms-excel");
            wb.write(output);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                output.close();
                wb.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }


    @GetMapping("searchDg")
    public String searchDg(Integer isSingle, Long houseId, Long bindHouseId, ModelMap modelMap) {
        modelMap.put("isSingle", isSingle == null ? 0 : isSingle);
        modelMap.put("houseId", houseId == null ? 0 : houseId);
        modelMap.put("bindHouseId", bindHouseId == null ? 0 : bindHouseId);
        return "/mMateriel/mMaterielDg";
    }

    @GetMapping("searchDgNew")
    public String searchDgNew(String goodsId, String skuValue, ModelMap modelMap) {
        modelMap.put("isSingle", 0);
        modelMap.put("houseId",0);
        modelMap.put("bindHouseId", 0);
        modelMap.put("goodsId", goodsId);
        modelMap.put("skuValue", skuValue);
        return "/tticar/mMaterielTticar/mMaterielRelative";
    }

    @GetMapping("/search")
    @ResponseBody
    public Page search(String searchText, String searchCar, Long houseId, Long bindHouseId, MyPage<MMateriel> page) {
        return mMaterielService.search(page, searchText, searchCar, houseId, bindHouseId);
    }

    @GetMapping("/searchForRelative")
    @ResponseBody
    public Page searchForRelative(String searchText, String searchCar, Long houseId, Long bindHouseId, MyPage<MMateriel> page) {
        //根据产品需求一件仓储存货可以被多件天天爱车商品关联
//        return mMaterielService.searchForRelative(page, searchText, searchCar, houseId, bindHouseId);
        return mMaterielService.search(page, searchText, searchCar, houseId, bindHouseId);
    }

    /**
     * 保存为存货提交
     * */
    @PostMapping("saveSubmit")
    @ResponseBody
    @Transactional(rollbackFor = Exception.class)
    public MyResponseBody saveSubmit(MMateriel mMateriel, String mMaterielSkuStr, String house, String carBrand,Long goodsId) {
        Wrapper wrapper = new EntityWrapper<>();
        wrapper.eq(MMateriel.NAME, mMateriel.getName());
        wrapper.ne("status", Status.DELETE.getCode());
        MMateriel materiel = mMaterielService.selectOne(wrapper);
        if (materiel != null && !materiel.getId().equals(mMateriel.getId())) {
            throw new MyServiceException("该存货商品已存在，请勿重复添加");
        }

        if (mMateriel.getDefaultUintId() == null) {
            throw new MyServiceException("基本信息：默认供应商栏不能为空");
        }
        if (StringUtils.isBlank(house)) {
            throw new MyServiceException("基本信息：仓库库位栏不能为空");
        }

        List<MMaterielSku> mMaterielSkus = JSONArray.parseArray(mMaterielSkuStr, MMaterielSku.class);
//        if (mMaterielSkus != null && mMaterielSkus.size() > 0) {
//            for (MMaterielSku skus : mMaterielSkus) {
//                if (skus.getBuyPrice() == null) {
//                    throw new MyServiceException("库存价格栏：进价不能为空");
//                }
//            }
//        }
        if (CollectionUtils.isEmpty(mMaterielSkus)) {
            throw new MyServiceException("库存价格不能为空");
        }

        // 校验：批发价>一级会员价>二级会员价>三级会员价
        for (MMaterielSku materielSku : mMaterielSkus) {
            if (StringUtils.isBlank(materielSku.getSkus())) {
                throw new MyServiceException("规格型号不能为空");
            }
            Map map = JSON.parseObject(materielSku.getPrices(), Map.class);
            List<BigDecimal> priceList = new ArrayList<>();
            String price0 = (String) map.get("0");
            String price1 = (String) map.get("1");
            String price2 = (String) map.get("2");
            String price3 = (String) map.get("3");
            if (price0 != null && !price0.equals("")) priceList.add(new BigDecimal(price0));
            if (price1 != null && !price1.equals("")) priceList.add(new BigDecimal(price1));
            if (price2 != null && !price2.equals("")) priceList.add(new BigDecimal(price2));
            if (price3 != null && !price3.equals("")) priceList.add(new BigDecimal(price3));

            if (priceList.size() > 1) {
                for (int i = 0; i < priceList.size()-1; i++) {
                    if (priceList.get(i).compareTo(priceList.get(i+1)) < 0) {
                        throw new MyServiceException("要求：批发价>=一级会员价>=二级会员价>=三级会员价");
                    }
                }
            }
        }

        List<CarBrandMateriel> carBrandList = JSONArray.parseArray(carBrand, CarBrandMateriel.class);
        mMateriel.setTticarGoodsId(goodsId);
        mMateriel.setStatus(0);
        mMaterielService.edit(mMateriel, mMaterielSkus, house, carBrandList);

        Wrapper w = new EntityWrapper<>();
        w.eq("tticar_goods_id", goodsId);
        w.eq("status", 0);
        MMateriel mMateriel1 = mMaterielService.selectOne(w);
        Wrapper wrapper1 = new EntityWrapper<>();
        wrapper1.eq("mid", mMateriel1.getId());
        List<MMaterielSku> mMaterielSkus1 = mMaterielSkuService.selectList(wrapper1);
        //进行关联
        List<SkuReturnToPage> skuValuesByGoodsId = goodsMapper.getSkuValuesByGoodsId(goodsId);
        for (int i = 0; i < skuValuesByGoodsId.size(); i++) {
            for (int j = 0; j<mMaterielSkus1.size();j++ ) {
                String skuName = skuValuesByGoodsId.get(i).getSkuName();
                if (mMaterielSkus1.get(j).getSkus().equals(skuName)) {
                    Long tenantId = MySecurityUtils.currentUser().getTenantId();
                    mskuMapper.insertRelativeTticarGoodsAndInvSku(goodsId.toString(), skuValuesByGoodsId.get(i).getSkuValue(), mMaterielSkus1.get(j).getId(),tenantId);
                }
            }
        }

        return MyResponseBody.success();
    }

    @GetMapping("queryInvMaterielList")
    @ResponseBody
    public List queryInvMaterielList(String invSkuId,HttpServletRequest request){
        Long skuLong = null;
        try {
            skuLong = Long.parseLong(invSkuId);
        } catch (Exception e) {

        }
        Map map = new HashMap<>(4);
        Map<String, String[]> parameterMap = request.getParameterMap();
        if (invSkuId == null && parameterMap.get("q") != null) {
            String goodsName = parameterMap.get("q")[0];
            if (goodsName.contains(":")) {
                goodsName = goodsName.substring(0, goodsName.indexOf(":")) + goodsName.substring(goodsName.indexOf(":")+1,goodsName.length());
            }
            map.put("goodsName", goodsName);
        }
        if (":".equals(invSkuId)) {
            return null;
        }
        if (invSkuId != null) {
            map.put("invSkuId", skuLong);
        }

        List list = mMaterielService.queryInvMaterielList(map);

        return list;
    }

    /**
     * 代下单取存货信息
     * */
    @GetMapping("materielListForPlaceOrder")
    @ResponseBody
    public List materielListForPlaceOrder(HttpServletRequest request) {
        Map map = new HashMap<>(2);
        Map<String, String[]> parameterMap = request.getParameterMap();
        if (parameterMap.get("q") != null) {
            String goodsName = parameterMap.get("q")[0];
            if (goodsName.contains(":")) {
                goodsName = goodsName.substring(0, goodsName.indexOf(":")) + goodsName.substring(goodsName.indexOf(":")+1,goodsName.length());
            }
            map.put("goodsName", goodsName);
        }

        List<PlaceOrderDTO> placeOrderDTOList = mMaterielMapper.materielListForPlaceOrder(map);
        if (placeOrderDTOList != null && placeOrderDTOList.size() > 0) {
            for (PlaceOrderDTO placeOrderDTO : placeOrderDTOList) {
                placeOrderDTO.setName(placeOrderDTO.getGoodsName() + "  " + placeOrderDTO.getSkuName());
            }
        }
        return placeOrderDTOList;
    }

    @PostMapping("getDetailsByRows")
    @ResponseBody
    public List getDetailsByRows(String rows) {
        if (StringUtils.isBlank(rows)) {
            return null;
        }
        List<PlaceOrderDTO> returnList = new ArrayList<>();
        List<PlaceOrderDTO> rowsList = JSONArray.parseArray(rows, PlaceOrderDTO.class);
        Map map = new HashMap<>(2);
        BigDecimal totalMoney = BigDecimal.ZERO;
        Integer totalCount = 0;
        for (int i=0;i<rowsList.size();i++) {
            map.put("materielSkuId", rowsList.get(i).getId());
            List<PlaceOrderDTO> placeOrderDTOs = mMaterielMapper.materielListForPlaceOrder(map);
            Wrapper wrapper = new EntityWrapper<>();
            wrapper.eq("id", MySecurityUtils.currentUser().getTenantId());
            SysTenant sysTenant = sysTenantService.selectOne(wrapper);

            PlaceOrderDTO dto = new PlaceOrderDTO();
            dto.setNeedInv(sysTenant.getNeedRelativeInv());
            dto.setCount(placeOrderDTOs.get(0).getCount());
            dto.setGoodsName(placeOrderDTOs.get(0).getGoodsName());
            dto.setSkuName(placeOrderDTOs.get(0).getSkuName());
            String prices = placeOrderDTOs.get(0).getPrices();
            Map<String,String> pricesMap = (Map) JSON.parse(prices);
            dto.setUnitPrice(new BigDecimal(pricesMap.get("0")));
            totalCount += rowsList.get(i).getCount();
            totalMoney = totalMoney.add(new BigDecimal(pricesMap.get("0")).multiply(new BigDecimal(rowsList.get(i).getCount())));
            if (i == rowsList.size() - 1) {
                dto.setTotalMoney(totalMoney);
                dto.setTotalCount(totalCount);
            }
            returnList.add(dto);
        }

        return returnList;
    }

}
